/**
 * Foo.java
 * 
 * Created on May 28, 2008 at 12:06:35 PM
 */
package org.lego4j;

/**
 * @author <a href="alexei.guevara@deftcompany.com">Alexei Guevara</>
 * @version $Revision:$ updated on $Date:$ by $Author:$
 */
public class Foo {
    
    private int myFailureCount = 0;
    
    private long myLastInvokedCheckedEx = 0;
    private long myCheckedExDelay = 0;
    
    private long myLastInvokedRuntimeEx = 0;
    private long myRuntimeExDelay = 0;

    private boolean myThrowsCheckedExNoRetryInvoked = false;
    private boolean myThrowsRuntimeExNoRetryInvoked = false;
    
    @RetryOnException(e=RuntimeEx.class, retries=1, delay=100)
    public void throwsRuntimeExRetry( RuntimeException theE ) throws RuntimeEx {
        if (this.myLastInvokedRuntimeEx!=0) {
            this.myRuntimeExDelay = System.currentTimeMillis() - this.myLastInvokedRuntimeEx;     
        }
        this.myLastInvokedRuntimeEx = System.currentTimeMillis();
        
        if (this.myFailureCount>0) {
            return;
        }
        this.myFailureCount++;
        throw theE; 
    }
    
    public void throwsCheckedExNoRetry( Exception theE ) throws Exception {
        if (!this.myThrowsCheckedExNoRetryInvoked) {
            this.myThrowsCheckedExNoRetryInvoked = true;
            throw theE;    
        }
    }
    
    public void throwsRuntimeExNoRetry( RuntimeException theE ) {
        if (!this.myThrowsRuntimeExNoRetryInvoked) {
            this.myThrowsRuntimeExNoRetryInvoked = true;
            throw theE;    
        }
    }

    @RetryOnException( e = {CheckedEx1.class, CheckedEx2.class}, retries = 1, delay=100 )
    public void throwsCheckedExRetry(Exception theE, int maxFailedAttempts) throws Exception {
        if (this.myLastInvokedCheckedEx!=0) {
            this.myCheckedExDelay = System.currentTimeMillis() - this.myLastInvokedCheckedEx;     
        }
        this.myLastInvokedCheckedEx = System.currentTimeMillis();
        
        if (this.myFailureCount>=maxFailedAttempts) {
            return;
        }
        this.myFailureCount++;
        throw theE; 
    }

    public long delayBetweenInvocationsOfBarThrowsCheckedEx() {
        return this.myCheckedExDelay;
    }

    public long delayBetweenInvocationsOfBarThrowsRuntimeEx() {
        return this.myRuntimeExDelay;
    }

    public void reset() {
        this.myFailureCount = 0;
        
        this.myLastInvokedCheckedEx = 0;
        this.myCheckedExDelay = 0;
        
        this.myLastInvokedRuntimeEx = 0;
        this.myRuntimeExDelay = 0;
    }

}
